package com.gxs.ea.fileupload.beans.jsf.outbox;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;

import org.json.JSONObject;
import org.primefaces.component.column.Column;
import org.primefaces.component.commandlink.CommandLink;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.component.inputtext.InputText;
import org.primefaces.component.outputlabel.OutputLabel;
import org.primefaces.component.panelgrid.PanelGrid;
import org.primefaces.component.row.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.gxs.ea.fileportal.domain.BaseCompany;
import com.gxs.ea.fileportal.domain.Field;
import com.gxs.ea.fileupload.beans.data.service.CompanyService;
import com.gxs.ea.fileupload.beans.data.service.FileMetaCollectionService;
import com.gxs.ea.fileupload.beans.utils.AuthUtils;
import com.gxs.ea.fileupload.beans.utils.JSFUtils;

@Component
@Scope("session")
public class SentBean  implements Serializable 
{
	
	@Autowired
	private JSFUtils jsfUtils;
	
	@Autowired
	private FileMetaCollectionService fileMetaCollectionService;
	
	@Autowired
	private AuthUtils authUtils;
	
	@Autowired
	private CompanyService companyService;
	
	private boolean viewParameterInit = false;
	
	private LazyFileTable listOfSentFiles;
	
	private static final int COLUMNS_PER_SEARCH_ROW = 2;
	
	private Map<String, String> labelsForSearchableFields = new HashMap<String, String>();
	
	boolean dynamicViewsDone = false;
	
	BaseCompany company = null;
	
	BaseCompany gxsCompany = null;
	
	private JSONObject[] selectedFileEntries;


	public SentBean()
	{
	}
	
	
	
	public CompanyService getCompanyService() {
		return companyService;
	}



	public void setCompanyService(CompanyService companyService) {
		this.companyService = companyService;
	}



	public BaseCompany getGxsCompany() 
	{
		if(gxsCompany == null)
		{
			gxsCompany = this.companyService.findByCompanyCode("gxs");
		}
		return gxsCompany;
	}



	public void setGxsCompany(BaseCompany gxsCompany) {
		this.gxsCompany = gxsCompany;
	}



	@PostConstruct
	public void initializeDataModel()
	{
		company = authUtils.getDetailsForLoggedInUser().getCompany();
		
		labelsForSearchableFields = new HashMap<String, String>();
		
		dynamicViewsDone = false;
		for(Field f : company.getCompanyMetaConfig().getFields() )
		{
			if(f.isSearchable())
				labelsForSearchableFields.put(f.getFieldName(), f.getFieldDisplayName());
		}
		for(Field f : getGxsCompany().getCompanyMetaConfig().getFields() )
		{
			if(f.isSearchable())
				labelsForSearchableFields.put(f.getFieldName(), f.getFieldDisplayName());
		}

		listOfSentFiles = new LazyFileTable(this.fileMetaCollectionService, company.getCompanyCode(), labelsForSearchableFields);
		dynamicViewsDone = false;
	}
	
	public boolean isViewParameterInit() {
		return viewParameterInit;
	}

	public void setViewParameterInit(boolean viewParameterInit) {
		// let it be false
		
		if(viewParameterInit)
			initializeDataModel();
	}

	
	public void initDynamicView()
	{
		System.out.println("Initializing dynamic views");
		renderDynamicFields();
	}

	private void renderDynamicFields() 
	{
		UIComponent panel = jsfUtils.findComponent("mainForm:searchFieldsPanel");
		
		if(panel == null || dynamicViewsDone)
			return;
		
		panel.getChildren().clear();
		
		Map<String, String> mapOfSearchFields = this.listOfSentFiles.getMapOfSearchFields();
		int numberOfRows = mapOfSearchFields.size() / COLUMNS_PER_SEARCH_ROW;
		int partialColumns = mapOfSearchFields.size() % COLUMNS_PER_SEARCH_ROW;
		if( partialColumns != 0)
			numberOfRows++;
		
		Iterator<String> searchFieldIterator = mapOfSearchFields.keySet().iterator();
		
		PanelGrid panelGrid = new PanelGrid();
		panelGrid.setStyleClass("noBorderGrid");
		panel.getChildren().add(panelGrid);
		
		boolean isLastRow = false;
		int rowNumber = 0;
		
		for(int i=0; i<numberOfRows; i++)
		{
			rowNumber++;
			if(rowNumber == numberOfRows)
			{
				isLastRow = true;
			}

			Row row = new Row();
			panelGrid.getChildren().add(row);
			int columnNumber = 0;
			
			for(int j=0; j<COLUMNS_PER_SEARCH_ROW; j++)
			{
				columnNumber++;
				
				if(isLastRow && partialColumns != 0 && columnNumber > partialColumns)
				{
					Column labelColumn = new Column();
					Column valueColumn = new Column();
					row.getChildren().add(labelColumn);
					row.getChildren().add(valueColumn);
				}
				else
				{
					// this is NOT a filler - but a regular data column
					String fieldName = searchFieldIterator.next();
					
					Column labelColumn = new Column();
					row.getChildren().add(labelColumn);
					
					OutputLabel outputLabel = new OutputLabel();
					outputLabel.setValue(this.labelsForSearchableFields.get(fieldName));
					labelColumn.getChildren().add(outputLabel);
					
					Column valueColumn = new Column();
					row.getChildren().add(valueColumn);
					
					InputText inputText = new InputText();
					String valueString = "#{sentBean.listOfSentFiles.mapOfSearchFields['===']}";
					valueString = valueString.replace("===", fieldName);
					inputText.setValueExpression("value", jsfUtils.createValueExpression(valueString));
					valueColumn.getChildren().add(inputText);
				}
			}
		}
		
		renderTable();
		
		dynamicViewsDone = true;
		
		
	}
	
	public void downloadSelectedFiles()
	{
		
		clearAllSelections();
		jsfUtils.printSuccess("Complete:", "The call completed, but this feature is not fully enabled yet");
	}

	public void clearAllSelections()
	{
		this.selectedFileEntries = null;
	}
	
	private void renderTable() 
	{
		
		UIComponent panel = jsfUtils.findComponent("mainForm:outputPanel");
		
		DataTable table = new DataTable();
	
		table.setId("filesDataTable");
		table.setWidgetVar("filesDataTableWidget");
		table.setValueExpression("value", jsfUtils.createValueExpression("#{sentBean.listOfSentFiles}"));
		table.setValueExpression("rendered", jsfUtils.createValueExpression("#{sentBean.listOfSentFiles != null}"));
		table.setVar("file");
		table.setPaginator(true);
		table.setRows(10);
		table.setCurrentPageReportTemplate("Showing {startRecord}-{endRecord} out of {totalRecords}");
		table.setPaginatorTemplate("{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {JumpToPageDropdown}");
		table.setRowsPerPageTemplate("5,10,15");
		table.setPaginatorPosition("bottom");
		table.setLazy(true);
		table.setSortBy("shipmentCity");
		table.setSortOrder("ASCENDING");
		
		table.setValueExpression("selection", jsfUtils.createValueExpression("#{sentBean.selectedFileEntries}"));
		
		panel.getChildren().add(table);
		
		company = authUtils.getDetailsForLoggedInUser().getCompany();
		
		//
		// Add Standard GXs field to this company first
		if(getGxsCompany() != null)
		{
			List<String> gxsHeadings = gxsCompany.getCompanyMetaConfig().getFieldGropuings();
			
			for(String currentgxsHeading : gxsHeadings)
			{
				List<String> currentGxsFields = gxsCompany.getCompanyMetaConfig().getMapOfOrderedFieldsForOutputSummaryTable().get(currentgxsHeading);
				
				if(currentGxsFields != null && currentGxsFields.size() > 0)
				{
					List<String> companyFieldsForCurrentGxsHeading = this.company.getCompanyMetaConfig().getMapOfOrderedFieldsForOutputSummaryTable().get(currentgxsHeading);
					
					if(companyFieldsForCurrentGxsHeading == null)
					{
						companyFieldsForCurrentGxsHeading = new ArrayList<String>();
						this.company.getCompanyMetaConfig().getMapOfOrderedFieldsForOutputSummaryTable().put(currentgxsHeading, companyFieldsForCurrentGxsHeading );
					}
					
					companyFieldsForCurrentGxsHeading.addAll(currentGxsFields);
				}
			}
		}
		
		//
		// Add selection column
		Column column = new Column();
		table.getChildren().add(column);
		column.setStyle("width:2%");
		column.setSelectionMode("multiple");
		column.setExportable(false);
		
		//
		// Add the view details column
		/**
				 <h:outputLink ajax="false" immediate="true" includeViewParams="true" value="#{request.contextPath}/pages/admin/companies/view.xhtml?id=#{company.id}&amp;init=true" >
					<h:outputText value="View and Configure"/>
					<!-- <h:graphicImage value="/images/icons/view.gif" style="border:0;margin:0px;"/>  -->
				</h:outputLink> 

		 */
		column = new Column();
		table.getChildren().add(column);
		column.setWidth("20px;");
		column.setExportable(false);
		
		CommandLink link = new CommandLink();
		column.getChildren().add(link);
		UIOutput out = new UIOutput();
		out.setValue("View");
		link.getChildren().add(out);
		link.setOnclick("PF('detailsDialogWidget').show();");
		
		// now build the table for selected fields
		for(List<String> listOfFields : company.getCompanyMetaConfig().getMapOfOrderedFieldsForOutputSummaryTable().values() )
		{
			for(String fieldName : listOfFields)
			{
				// 
				// Additional custom behavior
				Field f = getFieldFromCompanyMetaConfig(fieldName);

				column = new Column();
				table.getChildren().add(column);
				
//				column.setHeaderText(f.getFieldDisplayName());
				
				UIOutput facetColumnName = (UIOutput) FacesContext.getCurrentInstance().getApplication().createComponent(UIOutput.COMPONENT_TYPE);
				facetColumnName.setValue(f.getFieldDisplayName());
				column.getFacets().put("header", facetColumnName);
				
				UIOutput output = new UIOutput();
				column.getChildren().add(output);
				String expression = "#{file['===']}";
				expression = expression.replace("===", fieldName);
				output.setValueExpression("value", jsfUtils.createValueExpression(expression));
				
				if(f.isFilterable() )
				{
					column.setFilterBy(fieldName);
				}
				
				if(f.isSortable())
				{
					column.setSortBy(fieldName);
				}
				
			}
		}
	}
	
	private Field getFieldFromCompanyMetaConfig(String fieldName)
	{
		List<Field> fields = company.getCompanyMetaConfig().getFields();
		
		if(fieldName.startsWith("gxs"))
		{
			fields = getGxsCompany().getCompanyMetaConfig().getFields();
		}
		for(Field f : fields )
		{
			if (f.getFieldName().equals(fieldName))
			{
				return f;
			}
		}
		
		return null;
	}

	public void fetchSentFiles()
	{
		
	}

	public JSFUtils getJsfUtils() {
		return jsfUtils;
	}

	public void setJsfUtils(JSFUtils jsfUtils) {
		this.jsfUtils = jsfUtils;
	}

	public LazyFileTable getListOfSentFiles() 
	{
		return listOfSentFiles;
	}

	public void setListOfSentFiles(LazyFileTable listOfSentFiles) {
		this.listOfSentFiles = listOfSentFiles;
	}

	public FileMetaCollectionService getFileMetaCollectionService() 
	{
		return fileMetaCollectionService;
	}

	public void setFileMetaCollectionService(
			FileMetaCollectionService fileMetaCollectionService) {
		this.fileMetaCollectionService = fileMetaCollectionService;
	}

	public AuthUtils getAuthUtils() {
		return authUtils;
	}

	public void setAuthUtils(AuthUtils authUtils) {
		this.authUtils = authUtils;
	}

	public void resetAll()
	{
		this.listOfSentFiles.getMapOfSearchFields().clear();
	}

	public JSONObject[] getSelectedFileEntries() {
		return selectedFileEntries;
	}

	public void setSelectedFileEntries(JSONObject[] selectedFileEntries) {
		this.selectedFileEntries = selectedFileEntries;
	}
}
